package cn.lghuntfor.commons.sms.tencent.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.lghuntfor.commons.common.constants.ReturnMsg;
import cn.lghuntfor.commons.common.result.ReturnData;
import cn.lghuntfor.commons.sms.api.exception.SmsException;
import cn.lghuntfor.commons.sms.tencent.common.TencentSmsConsts;
import cn.lghuntfor.commons.sms.tencent.service.TencentSmsService;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.Map;

/**
 * 腾讯云短信服务实现
 * @author liaogang
 * @date 2021/2/1 15:43
 */
public class TencentSmsServiceImpl implements TencentSmsService {

    @Autowired
    private Credential cred;

    @Value("${spring.sms.tencent.sdkAppId}")
    private String sdkAppId;

    @Override
    public ReturnData<Object> sendMessage(String[] mobiles, String appId, String signature, String templateId, String[] params) {
        /* 必要步骤：
         * 实例化一个认证对象，入参需要传入腾讯云账户密钥对 secretId 和 secretKey
         * 本示例采用从环境变量读取的方式，需要预先在环境变量中设置这两个值
         * 您也可以直接在代码中写入密钥对，但需谨防泄露，不要将代码复制、上传或者分享给他人
         * CAM 密钥查询：https://console.cloud.tencent.com/cam/capi
         */
        /* 实例化 SMS 的 client 对象
         * 第二个参数是地域信息，可以直接填写字符串 ap-guangzhou，或者引用预设的常量 */
        SmsClient client = new SmsClient(cred, TencentSmsConsts.REGION);
        /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
         * 您可以直接查询 SDK 源码确定接口有哪些属性可以设置
         * 属性可能是基本类型，也可能引用了另一个数据结构
         * 推荐使用 IDE 进行开发，可以方便地跳转查阅各个接口和数据结构的文档说明 */
        SendSmsRequest req = new SendSmsRequest();
        /* 填充请求参数，这里 request 对象的成员变量即对应接口的入参
         * 您可以通过官网接口文档或跳转到 request 对象的定义处查看请求参数的定义
         * 基本类型的设置:
         * 帮助链接：
         * 短信控制台：https://console.cloud.tencent.com/smsv2
         * sms helper：https://cloud.tencent.com/document/product/382/3773 */
        /* 短信应用 ID: 在 [短信控制台] 添加应用后生成的实际 SDKAppID，例如1400006666 */
        req.setSmsSdkAppid(appId);
        /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名，可登录 [短信控制台] 查看签名信息 */
        req.setSign(signature);
        /* 模板 ID: 必须填写已审核通过的模板 ID，可登录 [短信控制台] 查看模板 ID */
        req.setTemplateID(templateId);
        /* 下发手机号码，采用 e.164 标准，+[国家或地区码][手机号]
         * 例如+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号*/
        for (int i = 0; i < mobiles.length; i++) {
            String mobile = mobiles[i];
            if (!StrUtil.startWith(mobile, "+86")) {
                mobiles[i] = "+86" + mobile;
            }
        }
        req.setPhoneNumberSet(mobiles);
        /* 模板参数: 若无模板参数，则设置为空*/
        req.setTemplateParamSet(params);
        /* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
         * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应 */
        SendSmsResponse res = null;
        try {
            res = client.SendSms(req);
        } catch (TencentCloudSDKException e) {
            throw new SmsException(ReturnMsg.SERVER_ERROR.getCode(), "短信发送失败");
        }
        // 可以取出单个值，您可以通过官网接口文档或跳转到 response 对象的定义处查看返回字段的定义
        return new ReturnData<>(res.getRequestId());
    }

    @Override
    public ReturnData<Object> sendMessage(String[] mobiles, String signature, String templateId, Map<String, String> params) {
        return sendMessage(mobiles, sdkAppId, signature, templateId, params.keySet().toArray(new String[0]));
    }

    @Override
    public ReturnData<Object> sendOverseaMessage(String mobile, String signature, String templateId, Map<String, String> params) {
        throw new SmsException(ReturnMsg.BAD_REQUEST.getCode(), "不支持此操作");
    }

    @Override
    public ReturnData<Object> sendFulltextMessage(String[] mobile, String content) {
        throw new SmsException(ReturnMsg.BAD_REQUEST.getCode(), "不支持此操作");
    }
}
